/*
 *  Copyright (c) 2018, Infineon Technologies AG
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification,are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *  - Neither the name of the copyright holders nor the names of its contributors
 *  may be used to endorse or promote products derived from this software without
 *  specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  To improve the quality of the software, users are encouraged to share
 *  modifications, enhancements or bug fixes with Infineon Technologies AG
 *  dave@infineon.com).
 */
/**
 * \defgroup PWM Pulse Width Modulation
 * Control of peripherals for PWM generation.
 * @{
 */
/**
 * \file    config_buck_pwm.h
 * \author  Manuel Escudero Rodriguez
 * \date    09.05.2018
 * \brief   Pulse Width Modulation
 */
#ifndef __CONFIG_BUCK_PWM_H_
#define __CONFIG_BUCK_PWM_H_

#include "config_pwm.h"

/*---------------------------------------------------------------------------*/
/**
 * \brief       Shifts lagging leg PWM
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_shift()
{
	static uint32_t previous_tick_blk; /* LEDs clock edge detector. [control_cyc] */
	uint16_t phase_out = (uint16_t) voltage_ctr.phase_out;
	/* Set new DAC start value- ramp is automatically generated */	
	peak_ref_set(phase_out);
	if(voltage_ctr.blk_phase < CSG_BLK)
	{
		if((converter_ctr.time_tick >> BLK_INC_PRSCLR) != previous_tick_blk)
		{
			previous_tick_blk = (converter_ctr.time_tick >> BLK_INC_PRSCLR);
			voltage_ctr.blk_phase ++;
			pwm_blk_set(voltage_ctr.blk_phase);
		}
	}
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Adjust synchronous rectification PWM duty cycle.
 * \return      None
 *
 * There is one mode of synchronous rectification in peak control:
 * 	-	During power transfer one of the synchronous rectifiers is maintained ON while the opposite is switched OFF.
 * 		During the overlap of PWM_A and PWM_D -> PWM_E would be switched OFF.
 * 		During the overlap of PWM_B and PWM_C -> PWM_F would be switched OFF.
 * 	The first mode is the used for medium and high loads.
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_sync_shift()
{
	static uint16_t pr_value; /* Period value of synchronous rectifier PWM. [CCU_clk] */
	static uint16_t cr_value; /* On time value of synchronous rectifier PWM. [CCU_clk] */
	int16_t cr_value_new; /* New turn on delay calculated. [CCU_clk] */
	uint16_t pr_value_new; /* New period calculated. [CCU_clk] */
	int16_t pr_adjusted_value;  /* New turn OFF delay calculated. [CCU_clk] */

	/*
	 * There is a minimum delay between the switch OFF of the gate before
	 * the voltage in the drain starts to rise, for safety reasons. This is taken
	 * into account by the MAX PERIOD value.
	 */
	/* Special driving scheme during DCM */
	if(converter_ctr.status & DCM)
	{
		/*
		 * Adaptive synchronous rectifiers driving scheme.
		 * An increase in the conduction time would be progressive for better regulation.
		 */
		cr_value_new = current_ctr.dt_A_B + SYNC_ON_DCM_DLY;
		cr_value_new = (cr_value_new > 0) ? cr_value_new : 0;
		cr_value = (cr_value > cr_value_new) ? cr_value - 1 : cr_value_new;
		/* Synch is ON during the power transfer primary-secondary only. */
		pr_value = PWM_A_B_DUTY;
		/* No extra delay in this mode. */
		pr_adjusted_value = 0;
	}
	else
	{
		/*
		 * Adaptive synchronous rectifiers driving scheme.
		 * An increase in the conduction time would be progressive for better regulation.
		 */
		cr_value_new = current_ctr.dt_C_D + SYNC_ON_DLY - current_ctr.synch_il_ON;
		cr_value_new = (cr_value_new > 0) ? cr_value_new : 0;
		cr_value = (cr_value > cr_value_new) ? cr_value - 1 : cr_value_new;
		/*
		 * Period is set to the maximum possible. The timers would be reset by the bridge signals.
		 * An increase in the conduction time is progressive to help regulation.
		 */
		pr_value_new = SYNC_MAX_PERIOD;
		pr_value = (pr_value_new > pr_value) ? pr_value + 1 : pr_value_new;
		/* Extra delay turn OFF. */
		pr_adjusted_value = current_ctr.dt_A_B - SYNC_OFF_DLY + current_ctr.synch_il_OFF;
		pr_adjusted_value = (pr_adjusted_value > 0) ? pr_adjusted_value : 0;
	}
	/*
	 * Even if the duty cycle is not updated on decreasing phase shift, the current adjustment should be
	 * updated in prevision of sudden load decrease which may cause the gate signal to overlap with the VDS voltage.
	 */
	/* Update new values into PWM. */
	PWM_E.ccu4_slice_ptr->CRS = cr_value;
	PWM_E.ccu4_slice_ptr->PRS = pr_value;
	/* Adaptive turn OFF delay of synchronous. */
	PWM_STOP_E.ccu4_slice_ptr->PRS = pr_adjusted_value;
	
	PWM_F.ccu4_slice_ptr->CRS = cr_value;
	PWM_F.ccu4_slice_ptr->PRS = pr_value;
	/* Adaptive turn OFF delay of synchronous. */
	PWM_STOP_F.ccu4_slice_ptr->PRS = pr_adjusted_value;	
	
    /* Triggers shadow transfer of all synch related timers. */
    PWM_F.ccu4_module_ptr->GCSS = PWM_E.shadow_txfr_msk | PWM_F.shadow_txfr_msk | PWM_STOP_E.shadow_txfr_msk | PWM_STOP_F.shadow_txfr_msk;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Synchronous DCM mode
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_sync_dcm_cfg()
{
	/* Deactivation of starting event before the reconfiguration. */
	PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
	PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
	/* Clear and stop timer. */
	PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
	PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
	
	/* 
	 * Activates stopping events in E and F timer slices. 
	 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
	 * Note: Event 0 is initally configured in pwm_init() to falling edge.
	 */
	PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
	PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
	PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
	PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
	PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
	PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
	PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
	PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
	/* 
	 * Activates starting events in E and F timer slices. 
	 * Event 1 from PWM_STOP_F (B falling edge) for PWM_E and PWM_STOP_E (A falling edge) for PWM_F.
	 * Note: Event 1 is initially configured by Dave().
	 */
	PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
	PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
	/* Input O -> PWM_STOP_F */
	PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
	/* Input M -> PWM_STOP_E */
	PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
	PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
	PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Synchronous DCM mode
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_sync_dcm()
{
	/* If synchronous was already running, let it run again. */
	if(PWM_E.ccu4_slice_ptr->CMC & ((uint32_t) CCU4_CC4_CMC_STRTS_Msk))
	{
		/* Deactivation of starting event before the reconfiguration. */
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		/* Clear and stop timer. */
		PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		
		/* 
		 * Activates stopping events in E and F timer slices. 
		 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
		 * Note: Event 0 is initally configured in pwm_init() to falling edge.
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		/* 
		 * Activates starting events in E and F timer slices. 
		 * Event 1 from PWM_STOP_F (B falling edge) for PWM_E and PWM_STOP_E (A falling edge) for PWM_F.
		 * Note: Event 1 is initially configured by Dave().
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		/* Input O -> PWM_STOP_F */
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		/* Input M -> PWM_STOP_E */
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		/* This enable starting events of timers. Is the difference with the else block. */
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
	}
	else
	{
		/* Deactivation of starting event before the reconfiguration. */
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		/* Clear and stop timer. */
		PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		
		/* 
		 * Activates stopping events in E and F timer slices. 
		 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
		 * Note: Event 0 is initally configured in pwm_init() to falling edge.
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		/* 
		 * Activates starting events in E and F timer slices. 
		 * Event 1 from PWM_STOP_F (B falling edge) for PWM_E and PWM_STOP_E (A falling edge) for PWM_F.
		 * Note: Event 1 is initially configured by Dave().
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		/* Input O -> PWM_STOP_F */
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		/* Input M -> PWM_STOP_E */
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
	}
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Synchronous standard mode
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_sync_standard()
{
	int16_t cr_value_new; /* New turn on delay calculated. [CCU_clk] */
	
	/* If synchronous was already running, go for standard mode. */
	if(PWM_E.ccu4_slice_ptr->CMC & ((uint32_t) CCU4_CC4_CMC_STRTS_Msk))
	{
		/* Deactivation of starting event before the reconfiguration. */
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		/* Clear and stop timer. */
		PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		
		/*
		 * Adaptive synchronous rectifiers driving scheme.
		 * An increase in the conduction time would be progressive for better regulation.
		 */
		cr_value_new = current_ctr.dt_C_D + SYNC_ON_DLY;// - current_ctr.synch_il_ON;
		cr_value_new = (cr_value_new > 0) ? cr_value_new : 0;
		/*
		 * Even if the duty cycle is not updated on decreasing phase shift, the current adjustment should be
		 * updated in prevision of sudden load decrease which may cause the gate signal to overlap with the VDS voltage.
		 */
		/* Update new values into PWM. */
		PWM_E.ccu4_slice_ptr->CRS = cr_value_new;
		PWM_F.ccu4_slice_ptr->CRS = cr_value_new;
	    /* Triggers shadow transfer of all synch related timers. */
	    PWM_F.ccu4_module_ptr->GCSS = PWM_E.shadow_txfr_msk | PWM_F.shadow_txfr_msk;
		
		/* 
		 * Activates stopping events in E and F timer slices.
		 * Event 1 from PWM_STOP_F (B falling edge) for PWM_F and PWM_STOP_E (A falling edge) for PWM_E.
		 * Note: Event 1 is initially configured by Dave(). 
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		/* Input M -> PWM_STOP_E */
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		/* Input O -> PWM_STOP_F */
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);	    
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		
		/* 
		 * Activates starting events in E and F timer slices.
		 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
		 * Note: Event 0 is initally configured in pwm_init() to falling edge.
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		/* This enable starting events of timers. Is the difference with the else block. */
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_0 << (uint32_t) CCU4_CC4_CMC_STRTS_Pos);
	}
	else
	{
		/* Deactivation of starting event before the reconfiguration. */
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
		/* Clear and stop timer. */
		PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
		PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
			
		/*
		 * Adaptive synchronous rectifiers driving scheme.
		 * An increase in the conduction time would be progressive for better regulation.
		 */
		cr_value_new = current_ctr.dt_C_D + SYNC_ON_DLY;// - current_ctr.synch_il_ON;
		cr_value_new = (cr_value_new > 0) ? cr_value_new : 0;
		/*
		 * Even if the duty cycle is not updated on decreasing phase shift, the current adjustment should be
		 * updated in prevision of sudden load decrease which may cause the gate signal to overlap with the VDS voltage.
		 */
		/* Update new values into PWM. */
		PWM_E.ccu4_slice_ptr->CRS = cr_value_new;
		PWM_F.ccu4_slice_ptr->CRS = cr_value_new;
	    /* Triggers shadow transfer of all synch related timers. */
	    PWM_F.ccu4_module_ptr->GCSS = PWM_E.shadow_txfr_msk | PWM_F.shadow_txfr_msk;
					
		/* 
		 * Activates stopping events in E and F timer slices.
		 * Event 1 from PWM_STOP_F (B falling edge) for PWM_F and PWM_STOP_E (A falling edge) for PWM_E. 
		 * Note: Event 1 is initially configured by Dave(). 
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
		/* Input M -> PWM_STOP_E */
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		/* Input O -> PWM_STOP_F */
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
		PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
		PWM_E.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);
		PWM_F.ccu4_slice_ptr->CMC |= ((uint32_t) XMC_CCU4_SLICE_EVENT_1 << (uint32_t) CCU4_CC4_CMC_ENDS_Pos);	
		
		/* 
		 * Activates starting events in E and F timer slices.
		 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
		 * Note: Event 0 is initally configured in pwm_init() to falling edge.
		 */
		PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV0EM_Msk);
		PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
		PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV0EM_Pos);
	}
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Starts synchronous rectifying
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void buck_pwm_sync_start()
{
    /* If the synchronous rectifier had been annulled */
	if(!(PWM_E.ccu4_slice_ptr->CMC & ((uint32_t) CCU4_CC4_CMC_STRTS_Msk)))
    {
		/* Activates starting events in E and F timer slices. */
		converter_ctr.status |= DCM;
		buck_pwm_sync_dcm_cfg();
    }
}
/*---------------------------------------------------------------------------*/
/**
 * \brief       Reconfigures PWM into buck mode back from boost mode.
 * \return      None
 */
#ifndef DOXYGEN_SKIP
__attribute__((section(".ram_code")))
#endif
static inline void boost_to_buck_pwm_cfg()
{
    /*
     * Comparison value 2 of the PWM_A_B triggers the stop event of the slice PWM_D.
     * Stop of PWM_D triggers start of PWM_C. This way the shift is adjusted by PWM_A_B means.
     */
	PWM_A_B.ccu8_slice_ptr->CR2S = (uint16_t) MAX_ADJ_PHASE;
    PWM_C.hrc_slice_ptr->SCR1 = 0;
    PWM_C.hrc_slice_ptr->SCR2 = 0;
    PWM_D.hrc_slice_ptr->SCR1 = 0;
    PWM_D.hrc_slice_ptr->SCR2 = 0;
    PWM_A_B.ccu8_module_ptr->GCSS = PWM_A_B.shadow_txfr_msk | PWM_C.shadow_txfr_msk | PWM_D.shadow_txfr_msk;
	
	/* Deactivation of starting event before the reconfiguration. */
	PWM_E.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
	PWM_F.ccu4_slice_ptr->CMC &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
	/* Clear and stop timers. */
	PWM_E.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
	PWM_F.ccu4_slice_ptr->TCCLR = ((uint32_t) CCU4_CC4_TCCLR_TRBC_Msk | (uint32_t) CCU4_CC4_TCCLR_TCC_Msk);
	
	/* CR has to be lower or equal than the lowest possible PR (0 in this mode). */
	PWM_STOP_E.ccu4_slice_ptr->CRS = 0;
	PWM_STOP_F.ccu4_slice_ptr->CRS = 0;	
	
    /* Triggers shadow transfer of all synch related timers. */
    PWM_F.ccu4_module_ptr->GCSS = PWM_STOP_E.shadow_txfr_msk | PWM_STOP_F.shadow_txfr_msk;

	/* 
	 * Activates stopping events in E and F timer slices. 
	 * Event 0 from HR0.Q1 (C) for PWM_E and HR0.Q3 (D) for PWM_F.
	 * Note: Event 0 is initally configured in pwm_init() to falling edge.
	 */
    PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV0IS_Pos));
    PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV0IS_Pos));    
    PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_F) << ((uint8_t) CCU4_CC4_INS_EV0IS_Pos);
    PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_F) << ((uint8_t) CCU4_CC4_INS_EV0IS_Pos);

	/* 
	 * Activates starting events in E and F timer slices. 
	 * Event 1 from PWM_STOP_F (B falling edge) for PWM_E and PWM_STOP_E (A falling edge) for PWM_F.
	 * Note: Event 1 is initially configured by Dave().
	 */
	PWM_E.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV1EM_Msk);
	PWM_F.ccu4_slice_ptr->INS &= ~((uint32_t) CCU4_CC4_INS_EV1EM_Msk);
	PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV1EM_Pos);
	PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE << (uint32_t) CCU4_CC4_INS_EV1EM_Pos);	
	PWM_E.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
	PWM_F.ccu4_slice_ptr->INS &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos));
	/* Input O -> PWM_STOP_F */
	PWM_E.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_O) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
	/* Input M -> PWM_STOP_E */
	PWM_F.ccu4_slice_ptr->INS |= ((uint32_t) XMC_CCU4_SLICE_INPUT_M) << ((uint8_t) CCU4_CC4_INS_EV1IS_Pos);
}
#endif /* __CONFIG_PWM_H_ */
/** @} */
